﻿using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Reflection.Emit;
using System.Web;
using System.Web.Services.Protocols;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using CustomControls;
using WebServiceStudio;
using System.Collections;
using Fare;
using System.Text.RegularExpressions;
//using Xunit;
//using Xunit.Extensions;
using Microsoft.WindowsAzure.Storage.Table;
using System.Runtime.Serialization.Formatters.Binary;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Web.Script.Serialization;
using System.Xml.Linq;
using System.Text;
using LoadGenerator;

namespace LoadController
{
    
    public partial class _Soap : Page
    {

        static Wsdl wsdl;

        private static List<Control> curControls;
        private static List<Control> curControlsRandom;
        private static List<Control> curValidationControlsRandom;

        private static List<CustomTreeNode> curTreeNodes;
        private static CustomTreeNode curTreeNode;
        private bool IsPostBackFromTreeView = false;
        private string ErrorStackTrace;
        private static List<object> ParameterListForInvoke;

        private static Random rnd = new Random();

        //speichert die Arraygrößen für jeden einzelnen Wert
        private static  Dictionary<string, int> ArrayValueDictionary;

        //private static bool IsRandomInvokeTested = false;
        //private static bool IsSingleInvokeTested = false;

        private bool IsPostBackFromInvokeMethodSingle = false;
        private bool IsPostBackFromInvokeMethodRandom = false;

        public Job job { get; set; }

        private static Assembly OnCurrentDomainAssemblyResolve(object sender, ResolveEventArgs args)
        {
            // this is absurdly expensive...don't do this more than once, or load the assembly file in a more efficient way
            // also, if the code you're using to compile the CodeDom assembly doesn't/hasn't used the referenced assembly yet, this won't work
            // and you should use Assembly.Load(...)
            foreach (Assembly @assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (@assembly.FullName.Equals(args.Name, StringComparison.OrdinalIgnoreCase))
                {
                    return @assembly;
                }
            }
            
            return null;
        }

        protected void Page_PreInit(object sender, EventArgs e)
        {
            //AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyResolve);
            AppDomain.CurrentDomain.AssemblyResolve += OnCurrentDomainAssemblyResolve;     

            if (!IsPostBack)
            {
                this.Reset();
            }

            Control myControl = GetPostBackControl(this.Page);

            if (curControls != null && ArrayValueDictionary != null)
            {
                foreach (string Item in this.Page.Master.Request.Form)
                {
                    if (Item.Contains("_btnAddTextBox"))
                    {
                        string id = Item.Split(new char[] { '$' }).Last().Split(new string[] { "_btnAddTextBox"},StringSplitOptions.None).First();
                        if (ArrayValueDictionary.ContainsKey(id))
                            ArrayValueDictionary[id] = ArrayValueDictionary[id] + 1;
                    }
                }
            }

            if (myControl != null)
            {
                if (myControl is System.Web.UI.WebControls.TreeView)
                {
                    string Selectedvalue = this.Page.Request.Params.Get("__EVENTARGUMENT");

                    string treeViewName = this.TreeViewService.ID;
                    string selnode = this.Page.Request.Params.Get("FeaturedContent_" + treeViewName + "_SelectedNode");
                    selnode = selnode.Split(new char[]{'t'}).Last();
                    int nodeIndex = Convert.ToInt32(selnode);
                    curTreeNode = curTreeNodes[nodeIndex];

                    IsPostBackFromTreeView = true;
                }

                if (myControl is System.Web.UI.WebControls.Button)
                {
                    if (myControl.ID.Equals("buttonGet"))
                        Reset();

                    if (myControl.ID.Equals("InvokeMethodSingle"))
                        IsPostBackFromInvokeMethodSingle = true;

                    if (myControl.ID.Equals("InvokeMethodRandom"))
                        IsPostBackFromInvokeMethodRandom = true;
                        
                }
            }
        }

        private void Reset()
        {
            curControls = null;
            curControlsRandom = null;
            curValidationControlsRandom = null;

            ArrayValueDictionary = null;
            controlCount = 0;
            curTreeNodes = null;
            curTreeNode = null;
            ParameterListForInvoke = null;

            //IsSingleInvokeTested = false;
            //IsRandomInvokeTested = false;
        }

        private void ResetAfterControlsInit()
        {
            this.LabelMethodName.Text = String.Empty;
            this.PagerControl.Style.Add("display", "none");
            PlaceHolderControls.Controls.Clear();
            TreeViewService.Nodes.Clear();

            //allways set these controls to visible = false
            this.PlaceHolderInvokeButton.Visible = false;
            this.PlaceHolderMessages.Visible = false;

            InvokeMethodSingleServer.Enabled = false;
            InvokeMethodRandomServer.Enabled = false;
        }

        private static int controlCount;
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            

            if (!IsPostBack)
            {
                this.ResetAfterControlsInit();
            }

            if (IsPostBackFromTreeView)
            {
                if (curTreeNode != null)
                {
                    MethodInfo mi = (MethodInfo)curTreeNode.Tag;
                    if (mi != null)
                    {
                        curControls = new List<Control>();
                        curControlsRandom = new List<Control>();
                        curValidationControlsRandom = new List<Control>();

                        ArrayValueDictionary = new Dictionary<string, int>();
                        controlCount = 1;

                        ParameterInfo[] pi = mi.GetParameters();
                        ParameterListForInvoke = new List<object>();
                        foreach (ParameterInfo pii in pi)
                        {
                            object obj = LoadController.InvokeHelper.CreateNewInstance(pii.ParameterType);
                            CreateControls(pii, obj);
                            ParameterListForInvoke.Add(obj);

                        }
                        
                    }
                }
                IsPostBackFromTreeView = false;
            }
            else
            {
                if (curControls != null)
                {
                    //adding the controls to webpage 
                    //every control is surrounded by a div control

                    //if array controls have been added to the view
                    bool ArrayControlsAdded = false;
                    
                    int i;
                    for (i = 0; i < curControls.Count; i++)
                    {
                        Control c = curControls[i];
                        //add the click eventhandler again
                        if (c is System.Web.UI.WebControls.Button)
                            ((Button)c).Click += new EventHandler(ArrayBtnAddTextBox_Click);


                        //check if control is type of array
                        if (c.ClientID.Contains("Array"))
                        {
                            //add it and his div closer
                            PlaceHolderControls.Controls.Add(curControls[i]);
                            PlaceHolderControls.Controls.Add(curControls[i + 1]);
                            i++;
                            //check, if there are more array controls, add them too

                            //get value name like pc.kommentare
                            string valName = c.ID.Split(new char[] { '_' })[1];

                            List<Control> arrControls = curControls.Where(control => control.ClientID.Contains("Array_" + valName)).ToList();
                            arrControls.Remove(c);

                            int arrControlCount = arrControls.Count();
                            //if count > 0, add controls

                            if (arrControlCount > 0)
                            {
                                int j;
                                for (j = i + 1; j <= i + arrControlCount * 3; j++)
                                    PlaceHolderControls.Controls.Add(curControls[j]);

                                i = j-1;
                            }

                            KeyValuePair<string, int> correspondingKVP = ArrayValueDictionary.Where(kvp => kvp.Key == valName).SingleOrDefault();

                            if (!String.IsNullOrEmpty(correspondingKVP.Key))
                            {
                                int arrDelta = correspondingKVP.Value - (arrControlCount + 1);

                                if (arrDelta > 0)
                                {
                                    TextBox curTextBox = (TextBox)c;

                                    int k;
                                    for (k = 1; k <= arrDelta; k++)
                                    {

                                        string newTextBoxId = "Array_" + correspondingKVP.Key + "_TextBox_" + (arrControlCount + 1 + k);
                                        TextBox textBoxToBeAdded = new TextBox();
                                        textBoxToBeAdded.CssClass = "with-helper";
                                        textBoxToBeAdded.ID = newTextBoxId;
                                        textBoxToBeAdded.Text = curTextBox.Text;

                                        PlaceHolderControls.Controls.Add(TEXTBOX_START_DIV);
                                        PlaceHolderControls.Controls.Add(textBoxToBeAdded);
                                        PlaceHolderControls.Controls.Add(TEXTBOX_END_DIV);
                                        ArrayControlsAdded = true;

                                        //this.CreateValidatorControls(t, textBoxToBeAdded.ID);
                                    }
                                }
                            }
                        }
                        else
                            PlaceHolderControls.Controls.Add(c);
                    }
                    
                    //rewrite internal control list
                    if (ArrayControlsAdded)
                    {
                        curControls = new List<Control>();
                        foreach (Control c in PlaceHolderControls.Controls)
                        {
                            curControls.Add(c);
                        }
                    }

                    //add controls for random invoke to placeholder
                    foreach (Control c in curControlsRandom)
                    {
                        PlaceHolderControlsRandom.Controls.Add(c);
                    }

                    //add validation controls for random invoke
                    foreach (Control c in curValidationControlsRandom)
                        PlaceHolderValidationControlsRandomInvoke.Controls.Add(c);
                }
            }
        }

        private void AddControlLabelHeader(PlaceHolder placeHolder, List<Control> toBeAddedControlList, string name, string type)
        {
            System.Web.UI.WebControls.Label label = new System.Web.UI.WebControls.Label();
            label.Text = name + " {" + type + "}";
            label.ID = name + "_" + type + "_Label_" + controlCount.ToString();
            label.CssClass = "ControlLabelHeader";

            placeHolder.Controls.Add(label);
            toBeAddedControlList.Add(label);
        }

        private void CreateControls(ParameterInfo pi, object obj, FieldInfo fi = null)
        {
            Type t = obj.GetType();

            //Control Label Header
            if (fi == null)
            {
                AddControlLabelHeader(PlaceHolderControls, curControls, pi.Name, pi.ParameterType.ToString());
                controlCount++;
                AddControlLabelHeader(PlaceHolderControlsRandom, curControlsRandom, pi.Name, pi.ParameterType.ToString());
            }
            else
            {
                AddControlLabelHeader(PlaceHolderControls, curControls, fi.Name, fi.FieldType.FullName);
                controlCount++;
                AddControlLabelHeader(PlaceHolderControlsRandom, curControlsRandom, fi.Name, fi.FieldType.FullName);
            }

            string name = String.Empty;
            if (fi != null) name = pi.Name + fi.Name; else name = pi.Name;

            //create different controls wrt type
            if (t == typeof(string))
            {
                CreateSimpleTextBox(PlaceHolderControls, curControls, "String_" + name + "_TextBox_" + controlCount.ToString(), obj.ToString());
                            
                //Create TextBox for string to define random values, ranges... 
                controlCount++;
                string textBoxID_Random = "Object_" + name + "_TextBox_Random_" + controlCount.ToString();

                string placeHolderText = "Enter strings like abc;def;ghi;";
                CreateSimpleTextBox(PlaceHolderControlsRandom, curControlsRandom, textBoxID_Random, null, false, placeHolderText);
            }
            else if (t.IsArray)
            {
                Button btnAddTextBox = new Button();
                btnAddTextBox.ID = name + "_btnAddTextBox_" + controlCount.ToString();
                btnAddTextBox.Text = "Array size +1";
                btnAddTextBox.Click += new EventHandler(ArrayBtnAddTextBox_Click);
                btnAddTextBox.EnableViewState = true;
                btnAddTextBox.CssClass = "mini";

                AsyncPostBackTrigger upt = new AsyncPostBackTrigger();
                upt.ControlID = btnAddTextBox.ID;
                upt.EventName = "Click";
                this.UpdatePanel1.Triggers.Add(upt);

                PlaceHolderControls.Controls.Add(new LiteralControl("<div class=\"row\">"));
                curControls.Add(new LiteralControl("<div class=\"row\">"));

                PlaceHolderControls.Controls.Add(btnAddTextBox);
                curControls.Add(btnAddTextBox);

                PlaceHolderControls.Controls.Add(new LiteralControl("</div>"));
                curControls.Add(new LiteralControl("</div>"));

                object ArrayInstance = LoadController.InvokeHelper.CreateNewInstance(obj.GetType().GetElementType());
                TextBox textbox = CreateSimpleTextBox(PlaceHolderControls, curControls, "Array_" + name + "_TextBox_1", ArrayInstance.ToString());

                ArrayValueDictionary.Add(name, 1);

                //this.CreateValidatorControls(t, btnAddTextBox.ID);

                //array controls for random invoke
                controlCount++;
                string placeHolderText = "Enter strings like abc;def;ghi;";

                Literal div = new Literal() { Text = "<div class=\"row\"><div class=\"span6\">", ID = "LiteralControl_" + (++controlCount).ToString() };
                PlaceHolderControlsRandom.Controls.Add(div);
                curControlsRandom.Add(div);

                TextBox textboxRandom = CreateSimpleTextBox(PlaceHolderControlsRandom, curControlsRandom, "Array_" + name + "_TextBox_Random_1", ArrayInstance.ToString(), false, placeHolderText);

                Literal div2 = new Literal() { Text = "</div><div class=\"span1\">", ID = "LiteralControl_" + (++controlCount).ToString() };
                PlaceHolderControlsRandom.Controls.Add(div2);
                curControlsRandom.Add(div2);

                TextBox textboxArraySize = CreateSimpleTextBox(PlaceHolderControlsRandom, curControlsRandom, "ArraySize_" + name + "_TextBox_Random_1", ArrayInstance.ToString(), true);

                Literal div3 = new Literal() { Text = "</div></div>", ID = "LiteralControl_" + (++controlCount).ToString() };
                PlaceHolderControlsRandom.Controls.Add(div3);
                curControlsRandom.Add(div3);

                
                //create validation controls for random invoke
                this.CreateValidatorControls(typeof(int), textboxArraySize.ID, PlaceHolderValidationControlsRandomInvoke, ValidationSummaryRandomInvoke);
            }
            else if (t.IsEnum)
            {
                DropDownList dropDownList = new DropDownList();
                dropDownList.ID = "Enum_"+ name + "_DropDownList_" + controlCount.ToString();

                Array test = obj.GetType().GetEnumValues();

                int k;
                for (k = 0; k < test.Length; k++)
                {
                    dropDownList.Items.Add(new ListItem(test.GetValue(k).ToString()));
                }

                PlaceHolderControls.Controls.Add(SELECT_START_DIV);
                curControls.Add(SELECT_START_DIV);

                PlaceHolderControls.Controls.Add(dropDownList);
                curControls.Add(dropDownList);

                PlaceHolderControls.Controls.Add(SELECT_END_DIV);
                curControls.Add(SELECT_END_DIV);

                //----------------------------------------------------------------
                //random stuff
                controlCount++;
                DropDownList dropDownList_Random = new DropDownList();
                dropDownList_Random.ID = "Enum_" + name + "_DropDownList_Random_" + controlCount.ToString();

                //add random entry
                dropDownList_Random.Items.Add(new ListItem("Random"));

                Array enumValues = obj.GetType().GetEnumValues();
                int p;
                for (p = 0; p < enumValues.Length; p++)
                {
                    dropDownList_Random.Items.Add(new ListItem(enumValues.GetValue(p).ToString()));
                }

                PlaceHolderControlsRandom.Controls.Add(SELECT_START_DIV);
                curControlsRandom.Add(SELECT_START_DIV);

                PlaceHolderControlsRandom.Controls.Add(dropDownList_Random);
                curControlsRandom.Add(dropDownList_Random);

                PlaceHolderControlsRandom.Controls.Add(SELECT_END_DIV);
                curControlsRandom.Add(SELECT_END_DIV);

            }
            else if (t == typeof(bool))
            {
                DropDownList dropDownList = new DropDownList();
                dropDownList.ID = "Bool_" + name + "_DropDownList_" + controlCount.ToString();
                dropDownList.Items.Add(new ListItem("false"));
                dropDownList.Items.Add(new ListItem("true"));

                PlaceHolderControls.Controls.Add(SELECT_START_DIV);
                curControls.Add(SELECT_START_DIV);

                PlaceHolderControls.Controls.Add(dropDownList);
                curControls.Add(dropDownList);

                PlaceHolderControls.Controls.Add(SELECT_END_DIV);
                curControls.Add(SELECT_END_DIV);

                //random stuff
                controlCount++;
                DropDownList dropDownList_Random = new DropDownList();
                dropDownList_Random.ID = "Bool_" + name + "_DropDownList_Random_" + controlCount.ToString();
                dropDownList_Random.Items.Add(new ListItem("Random"));
                dropDownList_Random.Items.Add(new ListItem("false"));
                dropDownList_Random.Items.Add(new ListItem("true"));

                PlaceHolderControlsRandom.Controls.Add(SELECT_START_DIV);
                curControlsRandom.Add(SELECT_START_DIV);

                PlaceHolderControlsRandom.Controls.Add(dropDownList_Random);
                curControlsRandom.Add(dropDownList_Random);

                PlaceHolderControlsRandom.Controls.Add(SELECT_END_DIV);
                curControlsRandom.Add(SELECT_END_DIV);
            }
            else if (t.IsClass)
            {
                PlaceHolderControls.Controls.Add(CLASS_OFFSET_START_DIV);
                curControls.Add(CLASS_OFFSET_START_DIV);

                PlaceHolderControlsRandom.Controls.Add(CLASS_OFFSET_START_DIV);
                curControlsRandom.Add(CLASS_OFFSET_START_DIV);

                foreach (FieldInfo f in obj.GetType().GetFields())
                {
                    object sub_obj = LoadController.InvokeHelper.CreateNewInstance(f.FieldType);
                    CreateControls(pi, sub_obj, f);
                    //set value of field
                    f.SetValue(obj, sub_obj);
                }

                PlaceHolderControls.Controls.Add(CLASS_OFFSET_END_DIV);
                curControls.Add(CLASS_OFFSET_END_DIV);

                PlaceHolderControlsRandom.Controls.Add(CLASS_OFFSET_END_DIV);
                curControlsRandom.Add(CLASS_OFFSET_END_DIV);
            }
            else
            {
                //Create TextBox for int, double...
                string textBoxID = "Object_" + name + "_TextBox_" + controlCount.ToString();
                CreateSimpleTextBox(PlaceHolderControls, curControls, textBoxID , obj.ToString());

                //--------------------------------------------------------------------
                //Create TextBox for int, double... to define random values, ranges... 
                controlCount++;
                string textBoxID_Random = "Object_" + name + "_TextBox_Random_" + controlCount.ToString();
                //string placeHolderText = "Enter range like 1-100;200-300;401;402...";
                string placeHolderText = "Enter regular expression";
                TextBox textbox = CreateSimpleTextBox(PlaceHolderControlsRandom, curControlsRandom, textBoxID_Random, null, false, placeHolderText);

                //Create Validation Control
                //this.CreateValidatorControls(t, textbox.ID, PlaceHolderValidationControlsRandomInvoke, ValidationSummaryRandomInvoke);
            }

            controlCount++;
        }

        private void CreateValidatorControls(Type t, string textBoxID, PlaceHolder ControlToBeAdded, ValidationSummary AssociatedVS)
        {
            CompareValidator cv = new CompareValidator();
            cv.ID = textBoxID + "_cv";
            cv.ControlToValidate = textBoxID;
            
            cv.Display = ValidatorDisplay.None;
            cv.ValidationGroup = AssociatedVS.ValidationGroup;
            cv.Operator = ValidationCompareOperator.DataTypeCheck;
            cv.ErrorMessage = textBoxID + ": Not a valid number";

            //RangeValidator rv = new RangeValidator();
            //rv.ID = textBoxID + "_rv";
            //rv.ControlToValidate = textBoxID;

            if (t == typeof(int))
            {
                //rv.MinimumValue = int.MinValue.ToString();
                //rv.MaximumValue = int.MaxValue.ToString();

                //rv.ErrorMessage = "Value must be a whole number between "
                //    + rv.MinimumValue + " and " + rv.MaximumValue;

                cv.Type = ValidationDataType.Integer;
                //rv.Type = ValidationDataType.Integer;
            }
            else if (t == typeof(Int16))
            {
                //rv.MinimumValue = Int16.MinValue.ToString();
                //rv.MaximumValue = Int16.MaxValue.ToString();

                //rv.ErrorMessage = "Value must be a whole number between "
                //    + rv.MinimumValue + " and " + rv.MaximumValue;

                cv.Type = ValidationDataType.Integer;
                //rv.Type = ValidationDataType.Integer;
            }
            else if (t == typeof(Int32))
            {
                //rv.MinimumValue = Int32.MinValue.ToString();
                //rv.MaximumValue = Int32.MaxValue.ToString();

                //rv.ErrorMessage = "Value must be a whole number between "
                //    + rv.MinimumValue + " and " + rv.MaximumValue;

                cv.Type = ValidationDataType.Integer;
                //rv.Type = ValidationDataType.Integer;
            }
            else if (t == typeof(Int64))
            {
                cv.Type = ValidationDataType.Integer;
                //rv.Type = ValidationDataType.Integer;
            }
            else if (t == typeof(double))
            {
                cv.Type = ValidationDataType.Double;
                //rv.Type = ValidationDataType.Double;
            }

            ControlToBeAdded.Controls.Add(cv);
            curValidationControlsRandom.Add(cv);

            //Int64 minvalue = 0;
            //object min = t.InvokeMember("MinValue", BindingFlags.GetField, null, minvalue, null);
            //minvalue = (Int64)min;

            //rv.MinimumValue = minvalue.ToString();

            //int maxvalue = 0;
            //object max = t.InvokeMember("MaxValue", BindingFlags.GetField, null, maxvalue, null);
            //maxvalue = (int)max;

            //rv.MaximumValue = maxvalue.ToString();
            //rv.ErrorMessage = "Value must be a whole number between "
            //    + minvalue.ToString() + " and " + maxvalue.ToString();

            //cv.Type = ValidationDataType.Integer;
            //rv.Type = ValidationDataType.Integer;

            //PlaceHolderValidationSummary.Controls.Add(cv);
            //curControls.Add(cv);
            //PlaceHolderValidationSummary.Controls.Add(rv);
            //curControls.Add(rv);
        }

        private TextBox CreateSimpleTextBox(PlaceHolder placeHolder, List<Control> toBeAddedControlList, string id, string text, bool validateControl = false, string buttonPlaceHolder = null)
        {
            TextBox textBox = new TextBox();
            textBox.CssClass = "with-helper";
            textBox.ID = id;
            textBox.Text = text;

            if (validateControl)
            {
                textBox.Attributes.Add("onkeyup", "Validate();");
                
                textBox.Attributes.Add("onchange", "Validate();");
            }

            if (buttonPlaceHolder != null)
                textBox.Attributes.Add("placeholder", buttonPlaceHolder);
            
            placeHolder.Controls.Add(TEXTBOX_START_DIV);
            toBeAddedControlList.Add(TEXTBOX_START_DIV);

            placeHolder.Controls.Add(textBox);
            toBeAddedControlList.Add(textBox);

            if (validateControl)
            {
                placeHolder.Controls.Add(TEXTBOX_END_DIV_VALIDATION(textBox.ClientID));
                toBeAddedControlList.Add(TEXTBOX_END_DIV_VALIDATION(textBox.ClientID));
            }
            else
            {
                placeHolder.Controls.Add(TEXTBOX_END_DIV);
                toBeAddedControlList.Add(TEXTBOX_END_DIV);
            }
            return textBox;
        }

        private void ArrayBtnAddTextBox_Click(object sender, EventArgs e)
        {
        }

        protected void btnAddTextBox_Click(object sender, EventArgs e)
        {
            // Handled in preInit due to event sequencing.
        }

        public static Control GetPostBackControl(Page thePage)
        {
            Control myControl = null;
            string ctrlName = thePage.Request.Params.Get("__EVENTTARGET");
            if (((ctrlName != null) & (ctrlName != string.Empty)))
            {
                myControl = thePage.Master.FindControl(ctrlName);
            }
            else
            {
                foreach (string Item in thePage.Master.Request.Form)
                {
                    Control c = thePage.FindControl(Item);
                    if (((c) is System.Web.UI.WebControls.Button))
                    {
                        myControl = c;
                    }
                }
            }
            return myControl;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void Page_LoadComplete(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(ErrorStackTrace))
            {
                this.ErrorMessageDialog.Style.Clear();
                this.ErrorMessageDialog.Style.Add(HtmlTextWriterStyle.Display, "none");

                if (IsPostBackFromInvokeMethodRandom)
                    this.InvokeMethodRandomServer.Enabled = true;

                if (IsPostBackFromInvokeMethodSingle)
                    this.InvokeMethodSingleServer.Enabled = true;
            }
            else
            {
                this.ErrorMessageDialog.Style.Add(HtmlTextWriterStyle.Display, "block");
                LabelErrorMessageDialog.Text = ErrorStackTrace;
                this.InvokeMethodRandomServer.Enabled = false;
                this.InvokeMethodSingleServer.Enabled = false;
                PlaceHolderMessages.Visible = false;
            }   
        }

        private Assembly AssemblyResolve(object sender, ResolveEventArgs args)
        {
            Assembly assembly = null;
            
            if (wsdl != null)
            {
                Assembly proxyAssembly = wsdl.ProxyAssembly;
                if (proxyAssembly != null)
                {
                    Assembly[] loadedass = AppDomain.CurrentDomain.GetAssemblies();

                    //string absfilename = proxyAssembly.ManifestModule.FullyQualifiedName;
                    string absfilename = Path.GetTempPath() + proxyAssembly.ManifestModule.Name;
                    //assembly = Assembly.Load(File.ReadAllBytes(absfilename));
                    //assembly = Assembly.LoadFrom(absfilename);
                    
                    //assembly = Assembly.Load(wsdl.ProxyAssembly.GetName());

                }
            }

            return assembly;
        }

        protected void buttonGet_Click(object sender, EventArgs e)
        {
            this.Reset();
            this.ResetAfterControlsInit();

            wsdl = new Wsdl();
            try
            {
                wsdl.Paths.Add(textEndPointUri.Text);
                wsdl.Generate();
                FillServiceTreeView();
            }
            catch (Exception ex)
            {
                ErrorStackTrace += ex.ToString(); 
            }
        }

        public static bool IsWebService(System.Type type)
        {
            return typeof(HttpWebClientProtocol).IsAssignableFrom(type);
        }

        public static bool IsWebMethod(MethodInfo method)
        {
            object[] customAttributes = method.GetCustomAttributes(typeof(SoapRpcMethodAttribute), true);
            if ((customAttributes != null) && (customAttributes.Length > 0))
            {
                return true;
            }
            customAttributes = method.GetCustomAttributes(typeof(SoapDocumentMethodAttribute), true);
            if ((customAttributes != null) && (customAttributes.Length > 0))
            {
                return true;
            }
            customAttributes = method.GetCustomAttributes(typeof(HttpMethodAttribute), true);
            return ((customAttributes != null) && (customAttributes.Length > 0));
        }

        private void FillServiceTreeView()
        {
            Assembly proxyAssembly = wsdl.ProxyAssembly;
            if (proxyAssembly != null)
            {
                curTreeNodes = new List<CustomTreeNode>();
                //this.TreeViewService.Nodes.Clear();
                foreach (System.Type type in proxyAssembly.GetTypes())
                {
                    if (IsWebService(type))
                    {            
                        CustomTreeNode root = new CustomTreeNode(type.Name, "~/CustomTreeView/globe.png");
                        TreeViewService.Nodes.Add(root);
                        curTreeNodes.Add(root);
             
                        foreach (MethodInfo info in type.GetMethods())
                        {
                            if (IsWebMethod(info))
                            {
                                CustomTreeNode node = new CustomTreeNode(info.Name, "~/CustomTreeView/method.png");
                                node.Tag = info;
                                root.ChildNodes.Add(node);
                                curTreeNodes.Add(node);
                            }
                        }
                         
                    }
                }
                this.TreeViewService.ExpandAll();
            }
        }

        protected void TreeViewService_SelectedNodeClicked(object sender, EventArgs e)
        {
            SelectedNode(sender, e);
        }

        protected void ServiceTreeView_SelectedNodeChanged(object sender, EventArgs e)
        {
            SelectedNode(sender, e);
        }

        private void SelectedNode(object sender, EventArgs e)
        {
            //allways set these controls to visible = false
            this.PlaceHolderInvokeButton.Visible = false;
            this.PlaceHolderMessages.Visible = false;

            InvokeMethodSingleServer.Enabled = false;
            InvokeMethodRandomServer.Enabled = false;

            CustomTreeNode node = (CustomTreeNode)((CustomTreeView)sender).SelectedNode;
            MethodInfo mi = (MethodInfo)node.Tag;
            if (mi != null)
            {
                this.LabelMethodName.Text = mi.Name;
                this.PlaceHolderInvokeButton.Visible = true;

                this.PagerControl.Style.Remove("display");

            }
            else
            {
                this.LabelMethodName.Text = String.Empty;
                this.PagerControl.Style.Remove("display");
                this.PagerControl.Style.Add("display", "none");
            }
        }

        public string ActivePage { get; set; }

        protected void InvokeMethodSingle_Click(object sender, EventArgs e)
        {
            ActivePage = "Page1";
            this.InternalInvokeMethod();
            //IsSingleInvokeTested = true;
        }

        protected void InvokeMethodSingleServer_Click(object sender, EventArgs e)
        {
            ActivePage = "Page1";
            CreateJobForInvoke(false);
        }

        protected void InvokeMethodRandom_Click(object sender, EventArgs e)
        {
            ActivePage = "Page2";
            this.InternalInvokeMethod(true);
            //IsRandomInvokeTested = true;
        }

        protected void InvokeMethodRandomServer_Click(object sender, EventArgs e)
        {
            ActivePage = "Page2";
            CreateJobForInvoke(true);
        }

        private void CreateJobForInvoke(bool IsRandomInvoke)
        {
            if (curTreeNode != null)
            {
                MethodInfo mi = (MethodInfo)curTreeNode.Tag;

                try
                {
                    //map values of controls to invoke parameters
                    Dictionary<string, object> strings = LoadController.InvokeHelper.GetContentListFromControls(curControlsRandom);

                    JavaScriptSerializer jsSerializer = new JavaScriptSerializer(new LoadController.CustomTypeResolver());
                    string parameters = jsSerializer.Serialize(strings);

                    job = new Job()
                    {
                        DllName = wsdl.ProxyAssembly.ManifestModule.Name,
                        ClassName = mi.DeclaringType.FullName,
                        MethodName = mi.Name,
                        Parameters = parameters,
                        ServiceName = textEndPointUri.Text,
                        IsRandomInvoke = IsRandomInvoke
                    };

                    //upload dll into blob storage
                    AzureBlobHelper.CreateBlobContainer(AppSettings.BlobContainer_assemblies);
                    CloudBlobContainer containerAss = AzureBlobHelper.GetContainerReference(AppSettings.BlobContainer_assemblies);

                    string blobName = wsdl.ProxyAssembly.ManifestModule.Name;
                    string filePath = wsdl.ProxyAssembly.Location;

                    AzureBlobHelper.UploadBlobIntoContainer(containerAss, blobName, filePath);

                }
                catch (Exception ex)
                {
                    Trace.Write(ex.ToString());
                    ErrorStackTrace += ex.ToString() + "<br /><br />";
                }
            }
        }

        private string ByteArrayToString(byte[] arr)
        {
            System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
            return enc.GetString(arr);
        }

        private void InternalInvokeMethod(bool IsRandomInvoke = false)
        {
            if (curTreeNode != null)
            {
                MethodInfo mi = (MethodInfo)curTreeNode.Tag;

                int loop;
                if (IsRandomInvoke)
                {
                    int invokeCount;
                    if (int.TryParse(InvokeCount.Text, out invokeCount))
                    {
                        if (invokeCount > 0)
                            loop = invokeCount;
                        else
                            loop = 1;
                    }
                    else
                        loop = 1;
                }
                else
                    loop = 1;

                InvokeCount.Text = loop.ToString();

                int i;
                for (i = 1; i <= loop; i++)
                {
                    try
                    {      
                        //map values of controls to invoke parameters
                        if (IsRandomInvoke)
                        {
                            Dictionary<string, object> strings = LoadController.InvokeHelper.GetContentListFromControls(curControlsRandom);
                            LoadController.InvokeHelper.MapRandomInvoke(strings, ref ParameterListForInvoke);
                        }
                        else
                        {
                            Dictionary<string, object> strings = LoadController.InvokeHelper.GetContentListFromControls(curControls);
                            LoadController.InvokeHelper.MapSingleInvoke(strings, ref ParameterListForInvoke, ArrayValueDictionary);
                        }

                        object[] objs = ParameterListForInvoke.ToArray();
                        object bla = Activator.CreateInstance(wsdl.ProxyAssembly.GetType(mi.DeclaringType.FullName));       
                        object result = mi.Invoke(bla, objs);
                    }
                    catch (Exception ex)
                    {
                        Trace.Write(ex.ToString());
                        ErrorStackTrace += ex.ToString() + System.Environment.NewLine + System.Environment.NewLine;
                    }

                    //Reading the logfile to get request and response stream
                    string filename = Path.GetTempPath() + mi.DeclaringType.FullName + ".log";
                    if (File.Exists(filename))
                    {
                        bool IsRequestLine = false;

                        string request = String.Empty;
                        string response = String.Empty;

                        foreach (string line in File.ReadLines(filename))
                        {
                            if (line.StartsWith("-----SoapRequest"))
                            {
                                IsRequestLine = true;
                                continue;
                            }

                            if (line.StartsWith("-----SoapResponse"))
                            {
                                IsRequestLine = false;
                                continue;
                            }

                            if (IsRequestLine)
                                request += line;
                            else
                                response += line;
                        }

                        Literal requestHeadLiteral = new Literal() { Text = "<tr><td><i class=\"icon-forward\"></i></td><td class=\"right\">" + i.ToString() + "</td><td><div class=\"xmlcontrol span10\">" };
                        Literal requestLiteral = new Literal() { Text = ApplieXsltToXML(request) };
                        Literal requestBottomLiteral = new Literal() { Text = "</div></td></tr>" };

                        PlaceHolderMessagesTable.Controls.Add(requestHeadLiteral);
                        PlaceHolderMessagesTable.Controls.Add(requestLiteral);
                        PlaceHolderMessagesTable.Controls.Add(requestBottomLiteral);

                        Literal responseHeadLiteral = new Literal() { Text = "<tr><td><i class=\"icon-reply\"></i></td><td class=\"right\">" + i.ToString() + "</td><td><div class=\"xmlcontrol span10\">" };
                        Literal responseLiteral = new Literal() { Text = ApplieXsltToXML(response) };
                        Literal responseBottomLiteral = new Literal() { Text = "</div></td></tr>" };

                        PlaceHolderMessagesTable.Controls.Add(responseHeadLiteral);
                        PlaceHolderMessagesTable.Controls.Add(responseLiteral);
                        PlaceHolderMessagesTable.Controls.Add(responseBottomLiteral);

                        this.PlaceHolderMessages.Visible = true;
                    }
                }

            }
        }

        private string ApplieXsltToXML(string xml)
        {
            XmlDocument xmlDoc = new XmlDocument();
            System.IO.Stream xmlStream;
            System.Xml.Xsl.XslCompiledTransform xsl = new System.Xml.Xsl.XslCompiledTransform();
            ASCIIEncoding enc = new ASCIIEncoding();
            System.IO.StringWriter writer = new System.IO.StringWriter();

            // Get Xsl
            xsl.Load(HttpContext.Current.Server.MapPath("/Content/defaultss.xslt"));

            // Remove the utf encoding as it causes problems with the XPathDocument
            xml = xml.Replace("utf-32", "");
            xml = xml.Replace("utf-16", "");
            xml = xml.Replace("utf-8", "");
            xmlDoc.LoadXml(xml);

            // Get the bytes
            xmlStream = new System.IO.MemoryStream(enc.GetBytes(xmlDoc.OuterXml), true);

            // Load Xpath document
            System.Xml.XPath.XPathDocument xp = new System.Xml.XPath.XPathDocument(xmlStream);

            // Perform Transform
            xsl.Transform(xp, null, writer);
            
            return writer.ToString();
        }

        #region LiteralControls

        private LiteralControl TEXTBOX_START_DIV
        {
            get
            {
                return new LiteralControl("<div class=\"input-control text\">") { ID = "LiteralControl_" + (++controlCount).ToString() };
            }
        }
        private LiteralControl TEXTBOX_END_DIV
        {
            get
            {
                return new LiteralControl("<button class=\"helper\" onclick=\"return false\"></button></div>") { ID = "LiteralControl_" + (++controlCount).ToString() };
            }
        }

        private LiteralControl TEXTBOX_END_DIV_VALIDATION(string controlIDToBeValidated)
        {
            return new LiteralControl("<button class=\"helper\" onclick=\"ClearContent('" + controlIDToBeValidated + "'); Validate();\"></button></div>") { ID = "LiteralControl_" + (++controlCount).ToString() };
        }

        private LiteralControl SELECT_START_DIV
        {
            get
            {
                return new LiteralControl("<div class=\"input-control select\">") { ID = "LiteralControl_" + (++controlCount).ToString() };
            }
        }
        private LiteralControl SELECT_END_DIV
        {
            get
            {
                return new LiteralControl("</div>") { ID = "LiteralControl_" + (++controlCount).ToString() };
            }
        }
        private LiteralControl CLASS_OFFSET_START_DIV
        {
            get
            {
                //return new LiteralControl("<div class=\"offset1\">") { ID = "LiteralControl_" + (++controlCount).ToString() };
                return new LiteralControl("<div class=\"border1-color-greenLight\">") { ID = "LiteralControl_" + (++controlCount).ToString() };
            }
        }
        private LiteralControl CLASS_OFFSET_END_DIV
        {
            get
            {
                return new LiteralControl("</div>") { ID = "LiteralControl_" + (++controlCount).ToString() };
            }
        }

        private LiteralControl CONTROL_LABEL_HEADER_START_DIV
        {
            get
            {
                return new LiteralControl("<div class=\"ControlLabelHeader\">") { ID = "LiteralControl_" + (++controlCount).ToString() };
            }
        }

        private LiteralControl END_DIV
        {
            get
            {
                return new LiteralControl("</div>") { ID = "LiteralControl_" + (++controlCount).ToString() };
            }
        }

        #endregion

    }

}